package com.project.frba.bi.descriptor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class Dimension {
	
	private String name;
	private Map<String, Property> properties = new LinkedHashMap<String, Property>();
	private Descriptor descriptor;
	
	public Dimension(String name, Descriptor descriptor){
		this.name = name;
		this.descriptor = descriptor;
	}

	public Collection<Property> getProperties(){
		return this.properties.values();
	}
	
	public Property getProperty(String propertyName){
		return this.properties.get(propertyName);
	}

	public String getName() {
		return name;
	}

	public void setName(String dimensionName) {
		this.name = dimensionName;
	}
	
	public Collection<String> getReferencedTables(){
		Set<String> tables = new TreeSet<String>();
		for (Property property : this.getProperties()) {
			tables.add(property.getTable());
		}
		return tables;
	}

	public Descriptor getDescriptor() {
		return descriptor;
	}

	public void setDescriptor(Descriptor descriptor) {
		this.descriptor = descriptor;
	}

	public String getJoinName(String table) {
		return ((DatabaseDescriptor)this.getDescriptor()).getJoinName(table);
	}
	
	public List<String> getPropertyNames(){
		List<String> propertyNames = new ArrayList<String>();
		for (Property property : this.getProperties()) {
			propertyNames.add(property.getName());
		}
		return propertyNames;
	}
	
	public Class getPropertyType(String propertyName){
		return properties.get(propertyName).getType();
	}
	
	public Node getMyNode() throws XPathExpressionException{
		return this.getDescriptor().getNode("//dimension[@name='" + this.getName() + "']");
	}

	public void loadProperties() throws XPathExpressionException{
		Node dimensionNode = this.getMyNode();
		NodeList propertyNodes = dimensionNode.getChildNodes();
		for (int i = 0; i < propertyNodes.getLength(); i++) {
			Node propertyNode = propertyNodes.item(i);
			if(propertyNode.getNodeName().equals("property")){
				String propertyName = propertyNode.getAttributes().getNamedItem("name").getNodeValue();
				Property property = new Property(propertyName, this);
				property.loadProperty();
			}
			
		}
	}

	public void addProperty(Property property) {
		this.properties.put(property.getName(), property);
		
	}

	public void loadDimension() throws XPathExpressionException {
		this.loadProperties();
		this.descriptor.addDimension(this);
	}
	
	public Boolean hasProperty(String propertyName){
		return this.properties.containsKey(propertyName);
	}
	
	public String getOlapAliasTable(){
		return this.getName().substring(0, 4);
	}

	public String getOlapAbsolutePath() {
		return descriptor.getDescriptorName() + this.getName() +  "dimension " + getOlapAliasTable();
	}
	
	public void removeProperty(String propertyName){
		this.properties.remove(propertyName);
	}

}
